package com.fablesoft.projectdatacollect.http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;

import com.fablesoft.projectdatacollect.MyApplication;
import com.fablesoft.projectdatacollect.bean.BaseResponse;
import com.fablesoft.projectdatacollect.util.CommonUtils;
import com.fablesoft.projectdatacollect.util.Config;
import com.fablesoft.projectdatacollect.util.Log4jUtil;
import com.fablesoft.projectdatacollect.util.LogUtil;
import com.fablesoft.projectdatacollect.util.PreferencesUtil;

import android.content.SharedPreferences.Editor;
import android.text.TextUtils;
import android.util.Log;

public final class HttpThread extends Thread {
	/**
	 * 日志标签
	 */
	private static final String TAG = "HttpThread";
	
	/**
	 * Handler what
	 */
	public static final int REQUEST_WAHT = -16;

	/**
	 * 用户控制是否中断请求的标志
	 */
	private boolean cancel = false;
	
	private boolean isGet = false;

	/**
	 * 请求url
	 */
	private String url;

	/**
	 * POST请求数据，如果为null则为GET方式，不为null时
	 * 
	 */
	private String data;

	/**
	 * HTTP请求监听的实现类，当请求有结果时会设置该类的相应方法
	 */
	private HttpListener listener;

	private Class clazz;
	
	private int timeout = 20000;

	/**
	 * 构造方法
	 * 
	 * @param url
	 *            请求url
	 * @param listener
	 *            实现监听请求状态的类
	 * @param clazz
	 *            返回对象class
	 */
	public HttpThread(String url, HttpListener listener, Class clazz, boolean isGet) {
		this.url = url;
		LogUtil.i(TAG, "url:" + url);
		// 如果data不为null，则为POST方式发送请求
		this.isGet = isGet;
		this.listener = listener;
		this.clazz = clazz;
	}
	
	public HttpThread(String url, HttpListener listener,
			Map<String, Object> params, Class clazz) {
		this.url = url;
		LogUtil.i(TAG, "url:" + url);
		// 如果data不为null，则为POST方式发送请求
		if (params != null) {
//			this.data = mapToString(params);
			this.data = JsonUtil.createReqStr(params);
		}
		this.listener = listener;
		this.clazz = clazz;
	}
	
	/**
	 * 构造方法
	 * 
	 * @param url
	 *            请求url
	 * @param listener
	 *            实现监听请求状态的类
	 * @param params
	 *            POST方式请求时的数据，如果为get方式发送，该字段为null
	 * @param clazz
	 *            返回对象class
	 */
	public HttpThread(String url, HttpListener listener,
			Map<String, Object> params, Class clazz, int timeout) {
		this.url = url;
		LogUtil.i(TAG, "url:" + url);
		// 如果data不为null，则为POST方式发送请求
		if (params != null) {
//			this.data = mapToString(params);
			this.data = JsonUtil.createReqStr(params);
		}
		this.listener = listener;
		this.clazz = clazz;
		this.timeout = timeout;
	}
	
	/**
	 * 发送HTTP请求，并将结果设置回HttpListener的实现类中
	 * 
	 */
	@Override
	public void run() {
		String result = null;

		result = sendRequest();

		// 如果用户还没有中断请求
		if (!cancel) {
			try {
				if(listener != null){
					BaseResponse response = JsonUtil.getResponse(result, clazz);
					if(response != null && "403".equals(response.getCode())){
						listener.onNotLogin(response);
					}else{
						listener.onRequestFinish(response);
					}
				}
			} catch (Exception e) {
				Log4jUtil.e(e.toString());
				e.printStackTrace();
			}
		}
	}

	
	
	/**
	 * 发送请求获取响应
	 * 
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	private String sendRequest() {
		URL myURL = null;
		HttpURLConnection conn = null;
		OutputStreamWriter out = null;
//		InputStream is = null;
		BufferedReader reader = null;
		StringBuffer response = new StringBuffer();
		try {
            Log.d(CommonUtils.TAG_UPLOAD, "upload url = " + url + ", params = " + data);
			myURL = new URL(url);
			conn = (HttpURLConnection) myURL.openConnection();
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			conn.setRequestProperty("Charset", "UTF-8");
			conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Content-Type",
                    "application/json; charset=utf-8");
			conn.setRequestProperty(Config.CLIENT_TYPE_KEY, Config.CLIENT_TYPE_VALUE);
			// 设置超时时间
			conn.setConnectTimeout(timeout);
			conn.setReadTimeout(timeout + 1000);
			LogUtil.i("lzx", "cookie:" + MyApplication.getInstance().getSessionId());
			if(!TextUtils.isEmpty(MyApplication.getInstance().getSessionId())){
				conn.setRequestProperty("Cookie", MyApplication.getInstance().getSessionId());
			}
			if (data != null) {
				LogUtil.i("lzx", "do post");
				conn.setRequestMethod("POST");
				LogUtil.i(TAG, "http post data is " + data);
				byte[] byteData = data.getBytes("UTF-8");
				conn.setRequestProperty("Content-Length",
						String.valueOf(byteData.length));
				out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
				out.write(data);
				out.flush();
			} else if (!isGet){
                LogUtil.i("lzx", "do post");
                conn.setRequestMethod("POST");
                conn.setDoOutput(false);
            } else {
				LogUtil.i("lzx", "do get");
				conn.setRequestMethod("GET");
                conn.setDoOutput(false);
			}
			if (conn.getResponseCode() == 200) {
				reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
				String key = null;
				String sessionId = "";  
		        String cookieVal = ""; 
				for(int i = 1; (key = conn.getHeaderFieldKey(i)) != null; i++){  
		            if(key.equalsIgnoreCase("set-cookie")){  
		                cookieVal = conn.getHeaderField(i);
		                LogUtil.i("lzx", "cookieVal:" + cookieVal);
		                cookieVal = cookieVal.substring(0, cookieVal.indexOf(";"));  
		                sessionId = sessionId + cookieVal + ";";  
		            }
		        }
//				if(TextUtils.isEmpty(MyApplication.getInstance().getSessionId())){
//					Editor editor = PreferencesUtil.getSharedPreferencesEditor(null);
//					editor.putString("sessionId", sessionId);
//					editor.commit();
					if(!TextUtils.isEmpty(sessionId) && Config.LOGIN_URL.equals(url)){
						LogUtil.i("lzx", "setSessionId:" + sessionId);
						Editor editor = PreferencesUtil.getSharedPreferencesEditor(null);
						editor.putString("sessionId", sessionId);
						editor.commit();
						MyApplication.getInstance().setSessionId(sessionId);
					}
					
//				}
					
	            String line;  
	            while ((line = reader.readLine()) != null) {  
	                response.append(line);
	            }  
//				byte[] buf = new byte[2048];
//				for (int n; (n = is.read(buf)) != -1;) {
//					response.append(new String(buf, 0, n, "UTF-8"));
//				}
			} 
//			else if(conn.getResponseCode() == 403){
//				MyApplication.getInstance().popAllActivityExceptOne(LoginActivity.class);
//				Intent intent = new Intent(MyApplication.getInstance(), LoginActivity.class);
//				intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//				MyApplication.getInstance().startActivity(intent);
//				is = new BufferedInputStream(conn.getErrorStream());
//				byte[] buf = new byte[1024];
//				for (int n; (n = is.read(buf)) != -1;) {
//					response.append(new String(buf, 0, n, "UTF-8"));
//				}
//				Log.e(TAG, "ResponseCode:" + conn.getResponseCode());
//			}
			else {
				Log.e(TAG, "ResponseCode:" + conn.getResponseCode());
			}
		} catch (Exception e) {
			Log4jUtil.e(e.toString());
			response = null;
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					Log4jUtil.e(e.toString());
					Log.e(TAG, "close outputStream " + e.toString());
				}
			}
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
					Log4jUtil.e(e.toString());
					Log.e(TAG, "close inputstream " + e.toString());
				}
			}
			if (conn != null) {
				conn.disconnect();
			}
		}
		Log.d(CommonUtils.TAG_UPLOAD, "response = " + response);
		return response == null || response.length() == 0 ? null : response.toString();
	}
}
